package com.example.first.thread;

import com.alibaba.fastjson.JSONObject;
import com.example.first.common.Constant;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;


/**
 * @Author LSQ
 * @Description Reentrantlock对象创建时要放在Runnable外面，不然怎么锁
 * @date 2021/11/5 21:47
 * @Version 1.0
 */

public class LearnReentrantLock4 {

    public static int count = 0;

    public static void main(String[] args) {

        ExecutorService executorService = new ThreadPoolExecutor(Constant.CORE_POOL_SIZE, Constant.MAX_POOL_SIZE,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(Constant.QUEUE_CAPACITY));

        List<People> peopleList = new LinkedList<>();

        for (int i = 0; i < 3; i++) {

            People people = new People(i, "lsq", i + 20, "golf", "$20000");
            peopleList.add(people);
        }


        final CountDownLatch countDownLatch = new CountDownLatch(peopleList.size());
        ReentrantLock reentrantLock = new ReentrantLock(true);

        peopleList.forEach(people -> {

            //Worker1 worker = new Worker1(people, countDownLatch);

            Runnable runnable = () -> {

                try {
                    reentrantLock.lock();
                    System.out.println(LocalDateTime.now() + " " + Thread.currentThread().getName() + " get lock!! start do" + JSONObject.toJSONString(people));

                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }


                    countDownLatch.countDown();

                } finally {
                    System.out.println(LocalDateTime.now() + " " + Thread.currentThread().getName() + " unlock! end do");
                    reentrantLock.unlock();

                }
            };

            executorService.submit(runnable);

        });

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        executorService.shutdown();

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (executorService.isTerminated()) {
            System.out.println(LocalDateTime.now() + " " + Thread.currentThread().getName() + " thread pool is terminated!");
        }


    }
}
